package main

import (
	"net"
	"google.golang.org/grpc"
	"../watcher"
	"../pb"
	"gopkg.in/alecthomas/kingpin.v2"
	"github.com/op/go-logging"
	"os"
	"github.com/valyala/fasthttp"
)

var (
	listen_addr  = kingpin.Flag("listen_addr", "listen address.").Required().Short('l').String()
	auth_addr    = kingpin.Flag("auth_addr", "auth address.").Short('a').String()
	prome_addr   = kingpin.Flag("prome_addr", "prometheus address.").Short('p').String()
	log_file     = kingpin.Flag("log", "log file.").String()
	watcher_conf = kingpin.Flag("conf", "conf file.").Required().Short('c').String()
	tags         = kingpin.Flag("tag", "tag key=value.").StringMap()
	log          = logging.MustGetLogger("watcher")
)

func main() {
	kingpin.Parse()
	if *log_file == "" {
		bk := logging.NewLogBackend(os.Stderr, "", 0)
		logging.SetBackend(bk)
	} else {
		file, err := os.OpenFile(*log_file, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
		if err != nil {
			log.Errorf("open log file %s , error: ", *log_file, err)
		}
		defer file.Close()
		bk := logging.NewLogBackend(file, "", 0)
		logging.SetBackend(bk)
	}

	lis, err := net.Listen("tcp", *listen_addr)
	if err != nil {
		log.Errorf("failed to listen: %v", err)
	}
	defer lis.Close()

	pws, err := watcher.NewProcWatcherService(*watcher_conf)
	if err != nil {
		log.Errorf("failed to start server: %v", err)
	}

	if *auth_addr != "" {
		conn, err := grpc.Dial(*auth_addr, grpc.WithInsecure())
		if err != nil {
			log.Errorf("failed create auth client: %v", err)
		}
		pws.SetAuth(conn)
	}

	metricMetric := watcher.NewMetrucExportor(60, []string{"UpTimeAndProcs", "Load", "Misc", "VirtualMemory", "SwapMemory", "CPU", "NetIOCounters", "TcpStatus", "DiskUsage", "DiskIOCounters"})

	if prome_addr != nil {
		log.Infof("start prometheus export on %s", *prome_addr)
		log.Infof("using tags: %v", *tags)
		go fasthttp.ListenAndServe(*prome_addr, func(ctx *fasthttp.RequestCtx) {
			switch string(ctx.Path()) {
			case "/host":
				b, err := metricMetric.Export(*tags)
				if err != nil {
					log.Error("export prometheus error: %v", err)
					ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
				} else {
					ctx.Success("text/plain; version=0.0.4", []byte(b))
				}
			case "/export":
				b, err := pws.Export(*tags)
				if err != nil {
					log.Error("export prometheus error: %v", err)
					ctx.Error(err.Error(), fasthttp.StatusInternalServerError)
				} else {
					ctx.Success("text/plain; version=0.0.4", []byte(b))
				}
			default:
				ctx.Error("", fasthttp.StatusNotFound)
			}
		})
	}
	watcher := grpc.NewServer()
	pb.RegisterWatcherServiceServer(watcher, pws)
	watcher.Serve(lis)
}
